package lab5p2;

/**
 * <p>Title: Hand</p>
 * <p>Description: CS 235 Assignment #1</p>
 * 
 * This class is used to represent an individual hand 
 * of playing cards.  The class has an array data member
 * of type PlayingCard to store the hand.  It is assumed 
 * that one hand can hold all the cards in a deck, so 
 * this is why the array size is initialized to 52.  The 
 * class has only a default constructor, a method to add
 * a card to the hand, a method to remove a card from the
 * hand, a method to return the size of the hand, a method
 * to display the contents of the hand, and a method to 
 * organize the contents of the hand.    
 * 
 * @author Nick Brown
 * @email nicholas.brown@my.uwrf.edu
 * @date February 25th 2013
 */

public class Hand
{
	static final int CARDS_IN_A_DECK = 52;
	
	// Data members to keep track of the size and contents of the hand.
	private int size;
	private PlayingCard[] hand;
	
	
	// Default constructor.  Initializes size to zero and creates a
	// new array to hold the PlayingCard objects that form the hand.
	public Hand()
	{
		size = 0;
		hand = new PlayingCard[CARDS_IN_A_DECK];
	}
	
	/* This method is used to add a PlayingCard object to the hand.
	 * It requires one parameter of type PlayingCard and does not
	 * return anything.  It assigns the array index, based on the 
	 * current size of the hand, to reference the PlayingCard object
	 * that was passed as the parameter.  After this assignment, the
	 * size data member is increased by one to reflect the addition.   
	 */
	public void addCard(PlayingCard card)
	{
		hand[size] = card;
		size ++;
	}
	
	/* This method is used to effectively remove a PlayingCard object
	 * from a hand.  It has one parameter of type integer, which is
	 * used to indicate the array index which references the card to
	 * be removed.  Because we need to account for any card that is
	 * removed, this method returns a reference to a PlayingCard 
	 * object, namely the card being removed.  To do this, we create
	 * a temporary reference called temp, and set this to reference the
	 * PlayingCard object to be removed from the hand.  We then set the 
	 * array index to a null reference, effectively removing the card 
	 * from the hand.  When this is complete, the size variable is 
	 * decremented to reflect the removal, and then a private method 
	 * named compress is called.  Please see the documentation of this 
	 * method below for full details on its operation.  Finally, the
	 * temporary reference to the removed PlayingCard object is returned.       
	 */
	public PlayingCard removeCard(int index)
	{
		PlayingCard temp = hand[index];
		hand[index] = null;
		size --;
		compress();
		return temp;
	}
	
	// This method simply returns the current size of the hand.
	public int getSize()
	{
		return size;
	}
	
	
	/* This method is used to display the contents of a hand.  It
	 * operates much the same as any other toString method, but 
	 * has some formatting modifications specific to this 
	 * application.   
	 */
	public String toString()
	{
		// Concatenation base
		String output = "";
		
		/* This for loop is used generate the String that will be
		 * returned at upon the completion of the method.  There
		 * is a little extra code written in to insert two newline
		 * characters if there are more than 9 cards in the hand, 
		 * and if the last card in the hand is being added to the 
		 * String, then there will be no comma after that card.
		 */
		for (int i = 0; i < size; i++)
		{
			if( i == 9)
			{
				output += "\n\n";
			}
			
			if( i == size - 1)
			{
				output += hand[i];
				break;
			}
			
			output += (hand[i] + ", ");  
		}
		
		return output;
	}
	
	/* This method is used to sort the array of PlayingCard objects 
	 * after any card has been removed.  It searches the array, 
	 * starting at the beginning, and looks for a null entry.  When 
	 * it finds one, it sets the current array index to reference 
	 * whatever the next array index is referencing.  It then sets 
	 * the next array index to null, and the loop continues until 
	 * all indices have been checked.  The final index that is 
	 * checked is the second to last.  Because of how this method
	 * is written, there is no need to check the last index.  The
	 * last index will always be set to null, unless the hand holds
	 * all 52 cards in the deck.    
	 */
	private void compress()
	{
		for (int i = 0; i < CARDS_IN_A_DECK - 1; i++)
		{
			if(hand[i] == null)
			{
				hand[i] = hand[i + 1];
				hand[i + 1] = null;
			}	
		}
	}
	
	// Sort method implements the Selection sort algorithm as
	//  described in http://en.wikipedia.org/wiki/Selection_sort
	// 
	public void sort(){
		compress();
		// We will sort the array of cards: hand[0] to hand[size-1]
		for (int i=0; i<size-1; i++){
			// assume the min is the first element of the next scan
			int jMin = i; 
			for (int j=i+1; j<size; j++) // scan the rest of the array for the smallest card
				if ( hand[j].compare( hand[jMin] ) < 0 )
					jMin = j; // found a new smallest card
			if (jMin != i){
				// swap positions of the i-th and jMin-th cards
				PlayingCard temp = hand[ i ];
				hand[ i ] = hand[ jMin ];
				hand[ jMin ] = temp;
			}				
		}
	}
}